package com.dfdchem.imd.kaiwu.activity;

import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.widget.PopupMenu;

import com.alibaba.android.arouter.facade.annotation.Autowired;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.dfdchem.imd.kaiwu.R;
import com.dfdchem.imd.kaiwu.activity.base.BaseActivity;
import com.dfdchem.imd.kaiwu.constant.RouterPath;
import com.dfdchem.imd.kaiwu.manager.IntranetManager;
import com.dfdchem.imd.kaiwu.util.VersionUtil;
import com.dfdchem.imd.kaiwu.webView.WebViewInterface;
import com.dfdchem.imd.kaiwu.webView.WebViewInterfaceCallback;
import com.scwang.smart.refresh.layout.api.RefreshLayout;
import com.scwang.smart.refresh.layout.listener.OnRefreshListener;
import com.tencent.smtt.export.external.extension.interfaces.IX5WebViewClientExtension;
import com.tencent.smtt.export.external.extension.proxy.ProxyWebViewClientExtension;
import com.tencent.smtt.export.external.interfaces.SslError;
import com.tencent.smtt.export.external.interfaces.SslErrorHandler;
import com.tencent.smtt.export.external.interfaces.WebResourceRequest;
import com.tencent.smtt.export.external.interfaces.WebResourceResponse;
import com.tencent.smtt.sdk.QbSdk;
import com.tencent.smtt.sdk.WebChromeClient;
import com.tencent.smtt.sdk.WebSettings;
import com.tencent.smtt.sdk.WebView;
import com.tencent.smtt.sdk.WebViewCallbackClient;
import com.tencent.smtt.sdk.WebViewClient;

import java.util.Map;

@Route(path = RouterPath.WEB_VIEW_X5_ACTIVITY)
public class WebViewX5Activity extends BaseActivity implements View.OnClickListener, PopupMenu.OnMenuItemClickListener, OnRefreshListener, WebViewInterfaceCallback {

    private static final String TAG = "WebViewX5Activity";

    /**
     * TODO
     * 1、调用JS方法，传递 X-Token 数据
     * 2、WebView 登录失效时，调用App方法，跳转到App登录页面，(并记录WebView最后一次访问的地址，然后登录完成后自动跳转回去)
     * 3、WebView 内链跳转支持
     * 4、WebView 跳转到Activity
     */

    @Autowired
    String title;

    @Autowired
    String content;

    @Autowired
    String url;

    @Autowired
    boolean full_screen = false;

    private TextView mTitleTextView;
    private View iv_back;
    private View iv_more;
    private View webview_tool_bar;
    private WebView mWebView;

    private RefreshLayout refreshLayout;

    private PopupMenu mPopupMenu;

    private ProgressBar mProgressBar;

    /**
     * 启动这个Activity的Intent
     * @param context
     * @return Intent
     */
    public static Intent createIntent(Context context) {
        return new Intent(context, WebViewX5Activity.class);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_webview_x5);

        initView();
        initData();
        initEvent();
    }

    @Override
    public void initView() {
        mTitleTextView = findView(R.id.web_view_toolbar_title);
        mProgressBar = findView(R.id.progressBar);
        mWebView = findView(R.id.webView_x5);
        webview_tool_bar = findView(R.id.webview_tool_bar);
        if (full_screen) {
            webview_tool_bar.setVisibility(View.GONE);
        }
        iv_back = findView(R.id.iv_back);
        iv_more = findView(R.id.iv_more);

        refreshLayout = (RefreshLayout) findViewById(R.id.refreshLayout);
        refreshLayout.setEnableRefresh(false);
        refreshLayout.setEnableLoadMore(false);
    }

    /**
     * 显示更多菜单
     *
     * @param view 菜单依附在该View下面
     */
    private void showPoPup(View view) {
        if (mPopupMenu == null) {
            mPopupMenu = new PopupMenu(this.getActivity(), view);
            mPopupMenu.inflate(R.menu.webview_toolbar_menu);
            mPopupMenu.setOnMenuItemClickListener(this);
        }
        mPopupMenu.show();
    }

    @Override
    public void initData() {
        mTitleTextView.setText(title);

        WebSettings webSetting = mWebView.getSettings();

        webSetting.setAllowFileAccess(true);
        webSetting.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
        webSetting.setSupportZoom(true);
        webSetting.setBuiltInZoomControls(true);
        webSetting.setUseWideViewPort(true);
        webSetting.setSupportMultipleWindows(false);
        // webSetting.setLoadWithOverviewMode(true);
        webSetting.setAppCacheEnabled(true);
        // webSetting.setDatabaseEnabled(true);
        webSetting.setMixedContentMode(android.webkit.WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
        webSetting.setDomStorageEnabled(true);
        webSetting.setJavaScriptEnabled(true);
        webSetting.setGeolocationEnabled(true);
        webSetting.setAppCacheMaxSize(Long.MAX_VALUE);
        webSetting.setAppCachePath(this.getDir("appcache", 0).getPath());
        webSetting.setDatabasePath(this.getDir("databases", 0).getPath());
        webSetting.setGeolocationDatabasePath(this.getDir("geolocation", 0)
                .getPath());
        // webSetting.setPageCacheCapacity(IX5WebSettings.DEFAULT_CACHE_CAPACITY);
        webSetting.setPluginState(WebSettings.PluginState.ON_DEMAND);
        // webSetting.setRenderPriority(WebSettings.RenderPriority.HIGH);
        // webSetting.setPreFectch(true);

        String ua = webSetting.getUserAgentString();
        ua += " " + getResources().getString(R.string.app_host) + "/" + VersionUtil.getAppVersionName(this);;
        webSetting.setUserAgentString(ua);

        if (url == null && content != null) {
            // 直接加载HTML内容
            mWebView.loadDataWithBaseURL(null, content, "text/html", "utf-8", null);
        } else {
            mWebView.loadUrl(url);
        }

        // 设置回调
        mWebView.setWebChromeClient(mWebChromeClient);
        mWebView.setWebViewClient(mWebViewClient);
        if (mWebView.getX5WebViewExtension() != null ){
            mWebView.getX5WebViewExtension().setWebViewClientExtension(mWebViewClientExtension);
        }

        mWebView.setWebViewCallbackClient(mCallbackClient);

        mWebView.addJavascriptInterface(new WebViewInterface(mWebView, context, this), "KWJSBridge");
    }

    private WebChromeClient mWebChromeClient = new WebChromeClient() {

        @Override
        public void onReceivedTitle(WebView webView, String s) {
            super.onReceivedTitle(webView, s);
            if (mTitleTextView != null) {
                mTitleTextView.setText(s);
            }
        }

        @Override
        public void onProgressChanged(WebView webView, int i) {
            super.onProgressChanged(webView, i);
            if (i == 100) {
                mProgressBar.setVisibility(View.GONE);
            } else {
                if (mProgressBar.getVisibility() == View.GONE)
                    mProgressBar.setVisibility(View.VISIBLE);
                mProgressBar.setProgress(i);
            }
        }
    };

    private WebViewClient mWebViewClient = new WebViewClient() {

        @Override
        public boolean shouldOverrideUrlLoading(WebView webView, WebResourceRequest webResourceRequest) {
            if (getResources().getString(R.string.app_scheme).equals(webResourceRequest.getUrl().getScheme())) {
                handleScheme(webResourceRequest.getUrl());
                return true;
            }
            return super.shouldOverrideUrlLoading(webView, webResourceRequest);
        }

        @Override
        public void onReceivedSslError(WebView webView, SslErrorHandler sslErrorHandler, SslError sslError) {
            super.onReceivedSslError(webView, sslErrorHandler, sslError);
            sslErrorHandler.proceed(); // 忽略证书错误的问题
        }

        @Override
        public com.tencent.smtt.export.external.interfaces.WebResourceResponse shouldInterceptRequest(WebView webView, WebResourceRequest webResourceRequest) {

            /**
             * 内外网资源转换
             */
            WebResourceRequest newRequest = new WebResourceRequest() {
                @Override
                public Uri getUrl() {
                    String url = webResourceRequest.getUrl().toString();
                    return Uri.parse(IntranetManager.convert(url));
                }

                @Override
                public boolean isForMainFrame() {
                    return webResourceRequest.isForMainFrame();
                }

                @RequiresApi(api = Build.VERSION_CODES.N)
                @Override
                public boolean isRedirect() {
                    return webResourceRequest.isRedirect();
                }

                @Override
                public boolean hasGesture() {
                    return webResourceRequest.hasGesture();
                }

                @Override
                public String getMethod() {
                    return webResourceRequest.getMethod();
                }

                @Override
                public Map<String, String> getRequestHeaders() {
                    return webResourceRequest.getRequestHeaders();
                }
            };
            Log.d(TAG, webResourceRequest.getUrl() + "  =>  " + newRequest.getUrl());
            return super.shouldInterceptRequest(webView, newRequest);
        }
    };

    private CallbackClient mCallbackClient = new CallbackClient();

    private class CallbackClient implements WebViewCallbackClient {


        @Override
        public boolean onTouchEvent(MotionEvent motionEvent, View view) {
            return mWebView.super_onTouchEvent(motionEvent);
        }

        @Override
        public boolean overScrollBy(int deltaX, int deltaY, int scrollX,
                                    int scrollY, int scrollRangeX, int scrollRangeY,
                                    int maxOverScrollX, int maxOverScrollY,
                                    boolean isTouchEvent, View view) {
            return mWebView.super_overScrollBy(deltaX, deltaY, scrollX, scrollY,
                    scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY,
                    isTouchEvent);
        }

        @Override
        public boolean dispatchTouchEvent(MotionEvent motionEvent, View view) {
            return mWebView.super_dispatchTouchEvent(motionEvent);
        }

        @Override
        public void computeScroll(View view) {
            mWebView.super_computeScroll();
        }

        @Override
        public void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY, View view) {
            mWebView.super_onOverScrolled(scrollX, scrollY, clampedX, clampedY);
        }

        @Override
        public boolean onInterceptTouchEvent(MotionEvent motionEvent, View view) {
            return mWebView.super_onInterceptTouchEvent(motionEvent);
        }

        @Override
        public void onScrollChanged(int l, int t, int oldl, int oldt, View view) {
            mWebView.super_onScrollChanged(l, t, oldl, oldt);
        }

        @Override
        public void invalidate() {
        }
    }

    private IX5WebViewClientExtension mWebViewClientExtension = new ProxyWebViewClientExtension() {
        public void invalidate() { }

        public void onReceivedViewSource(String data) {};

        @Override
        public boolean onTouchEvent(MotionEvent event, View view) {
            return mCallbackClient.onTouchEvent(event, view);
        }

        public boolean onInterceptTouchEvent(MotionEvent ev, View view) {
            return mCallbackClient.onInterceptTouchEvent(ev, view);
        }

        public boolean dispatchTouchEvent(MotionEvent ev, View view) {
            return mCallbackClient.dispatchTouchEvent(ev, view);
        }

        public boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY,
                                    int scrollRangeX, int scrollRangeY,
                                    int maxOverScrollX, int maxOverScrollY,
                                    boolean isTouchEvent, View view) {
            return mCallbackClient.overScrollBy(deltaX, deltaY, scrollX, scrollY,
                    scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent, view);
        }

        public void onScrollChanged(int l, int t, int oldl, int oldt, View view) {
            mCallbackClient.onScrollChanged(l, t, oldl, oldt, view);
        }

        public void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY, View view) {
            // 防止下拉刷新冲突
            /*if (scrollY > 0) {
                refreshLayout.setEnableRefresh(false);
            } else {
                refreshLayout.setEnableRefresh(true);
            }*/
            mCallbackClient.onOverScrolled(scrollX, scrollY, clampedX, clampedY, view);
        }

        public void computeScroll(View view) {
            mCallbackClient.computeScroll(view);
        }

        @Override
        public void onResponseReceived(WebResourceRequest request, WebResourceResponse response, int errorCode) {
            super.onResponseReceived(request, response, errorCode);
        }
    };

    @Override
    public void initEvent() {
        iv_more.setOnClickListener(this);
        iv_back.setOnClickListener(this);
        if (refreshLayout != null)
            refreshLayout.setOnRefreshListener(this);
    }

    @Override
    protected void onPause() {
        mWebView.onPause();
        super.onPause();
    }

    @Override
    protected void onResume() {
        mWebView.onResume();
        super.onResume();
    }

    @Override
    public void onDestroy() {
        mWebView.removeJavascriptInterface("JSKit");
        mWebView.destroy();
        super.onDestroy();
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.iv_more:
                showPoPup(v);
                break;
            case R.id.iv_back:
                onBackPressed();
                break;
        }
    }

    @Override
    public void onReturnClick(View v) {
        finish();
    }

    @Override
    public void onBackPressed() {
        if (mWebView.canGoBack()) {
            mWebView.goBack();
        } else {
            super.onBackPressed();
        }
    }

    @Override
    public boolean onMenuItemClick(MenuItem item) {
        switch (item.getItemId()) {

            case R.id.refresh:
                if (mWebView != null) {
                    mWebView.reload(); // 刷新
                }
                return true;

            case R.id.copy:
                if (mWebView != null) {
                    toCopy(this, mWebView.getUrl());
                    showShortToast("复制链接成功");
                }
                return true;
            case R.id.default_browser:
                if (mWebView != null) {
                    openBrowser(mWebView.getUrl());
                }
                return true;
            case R.id.default_clean:
                toCleanWebCache();
                return true;
            default:
                return false;
        }
    }

    /**
     * 复制字符串
     *
     * @param context
     * @param text
     */
    private void toCopy(Context context, String text) {
        ClipboardManager mClipboardManager = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
        if (mClipboardManager != null) {
            mClipboardManager.setPrimaryClip(ClipData.newPlainText(null, text));
        }
    }

    /**
     * 打开浏览器
     *
     * @param targetUrl 外部浏览器打开的地址
     */
    private void openBrowser(String targetUrl) {
        if (TextUtils.isEmpty(targetUrl) || targetUrl.startsWith("file://") || targetUrl.startsWith("kaiwu://")) {
            Toast.makeText(this, targetUrl + " 该链接无法使用浏览器打开。", Toast.LENGTH_SHORT).show();
            return;
        }
        Intent intent = new Intent();
        intent.setAction("android.intent.action.VIEW");
        Uri mUri = Uri.parse(targetUrl);
        intent.setData(mUri);
        startActivity(intent);
    }

    /**
     * 清除 WebView 缓存
     */
    private void toCleanWebCache() {
        if (this.mWebView != null) {
            //清理所有跟WebView相关的缓存 ，数据库， 历史记录 等。
            this.mWebView.clearCache(true);
            QbSdk.clearAllWebViewCache(WebViewX5Activity.this, true);
            Toast.makeText(getActivity(), "已清理缓存", Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void onRefresh(@NonNull RefreshLayout refreshLayout) {
        if (mWebView != null) {
            mWebView.reload(); // 刷新
            refreshLayout.finishRefresh(500);
        }
    }

    @Override
    public void goLogin(String jsCallback) {
        Log.d(TAG, "goLogin jsCallback:" + jsCallback);

        // 这里只负责启动 LoginActivity, 清除 X-Token 在 LoginActivity 初始化的时候做
        Intent intent = new Intent(WebViewX5Activity.this, LoginActivity.class);
        startActivity(intent);

        // 发送 LoginRequiredBroadcast.NAME 广播，已启动的需要登录的 Activity 调用 finish
        Intent intent_finish = new Intent();
        intent_finish.setAction(LoginRequiredBroadcast.NAME);
        sendBroadcast(intent_finish);
    }
}
